/*
UTF-8
*/
#ifndef _USER_KEY_H_
#define _USER_KEY_H_

/*
库说明：
    功能：
    实现通过读取外部IO状态，判断按键的按下，松开，单击，连击等事件
    说明：
    最多支持8个按键
    仅仅支持独立按键，矩阵扫描不支持
*/

/*
版本说明
    2020 04 18
    V1.0.0
    完善修改了使用例子
    增加宏定义USER_KEY_COUNT，用于配置当前按键数量
    增加宏定义USER_KEY_DOWN_HARDWARE_STATE 用于配置按键按下后硬件的对应状态配置
    将分别处理不同的按键事件，改为了循环处理不同按键的事件
    
    V1.0.1   20200706
    修改使用例子说明中的几处错误
    
*/


/*
使用例子
#第一步：先实现IO读取函数，如KEY_START_get
    uint8 KEY_STATE_get(uint8 key)
    {
        switch(key)
        {
            case 0:return io1_get();break;
            case 1:return io2_get();break;
            case 2:return io3_get();break;
            case 3:return io4_get();break;
            .
            .
            .
            case USER_KEY_COUNT-1:return io8_get();break;
        }
    }
    
#第二步：实现需要用到的按键事件，不需要的可以不实现，时间参数的基本单位由scan传递的参数决定
    可选，松开事件，key指明具体的按键是哪一个，time表明按下到松开持续的时间
    void key_callback_up(uint8_t key,uint16_t time)
    {
        switch(key)
        {
            case 0:break;
            case 1:break;
            ...
            case USER_KEY_COUNT-1:break;
        }
    }
    可选，按下事件，key指明具体的按键是哪一个，time无效
    void key_callback_down(uint8_t key,uint16_t time)
    {
        switch(key)
        {
            case 0:break;
            case 1:break;
            ...
            case USER_KEY_COUNT-1:break;
        }
    }
    可选，连击事件，key指明具体的按键是哪一个，count表明按了几下，单击返回1，双击返回2，支持多连击
    void key_callback_click(uint8_t key,uint16_t count)
    {
        switch(key)
        {
            case 0:break;
            case 1:break;
            ...
            case USER_KEY_COUNT-1:break;
        }
    }
    可选，长按事件，当按键按下后系统会持续调用该函数，调用频率为扫描频率
        key指明具体的按键是哪一个，time为从按下开始到当前的时间
    void key_longdown(uint8_t key,uint16_t time)
    {
        switch(key)
        {
            case 0:break;
            case 1:break;
            ...
            case USER_KEY_COUNT-1:break;
        }
    }
#第三步：初始化按键库
    user_key_init详细参数可以参考源码
    KEY_START_get为IO获取函数，后面4个参数为需要用到的事件函数，由步骤2实现
    不需要用到的事件可以直接填0，比如此处没有用到长按事件我们填入0
    
    void main()
    {
        //初始化
        user_key_init(KEY_STATE_get,key_callback_up,key_callback_down,0,key_callback_click);
        while(1)
        {
        }
    }
#第四步：定时扫描按键
    user_key_run需要定时调用，并传递一个扫描时间间隔的时间基本单位，一般调用时间为20-200毫秒即可
    扫描越快按键响应越快，同时消耗的资源越多
    void timer_100ms(uint32_t time)//100毫秒定时器
    {
        //传入调用时间间隔
        user_key_run(100);
    }









*/



#ifndef uint8
#define uint8 unsigned char
#endif

#ifndef uint16
#define uint16 unsigned short int
#endif

#ifndef uint32
#define uint32 unsigned int
#endif


/*
功能：按键变化事件
参数：参数1中包含按键变化的特征值，参数2包含按键按下的时间
返回值：无
*/
typedef void (*KeyEventCallback)(uint8,uint16);  				//*定义具有两个参数的函数指针的新类型*/

//定义一个函数类型，用于按键获取硬件io状态,返回IO的状态，必须是0或1值
typedef uint8(*KeyIoHardwareStateGet)(uint8); 


//连按统计时间
#define SHORT_DOWN_TIME_MS				        500

//连击延迟响应时间
#define CLICK_TIME_OUT					        1000


//长按起始触发时间
#define USER_KEY_LONG_DOWN_TIG_TIME				100


//配置当前按键数，不能超过32个
#define USER_KEY_COUNT                      3

//配置按键按下后，硬件IO获取到的是低电平还是高电平，数量要和USER_KEY_COUNT保持一致
#define USER_KEY_DOWN_HARDWARE_STATE        {1,0,0}





void user_key_init(KeyIoHardwareStateGet state_get,
					KeyEventCallback upx,
					KeyEventCallback downTime,
					KeyEventCallback longdownx,
					KeyEventCallback downCount);


void user_key_run(uint16 divtime);




#endif
